<?php


namespace common\helpers;

use GuzzleHttp\Client;
use yii;
use yii\helpers\Json;
use yii\web\Response;
use yii\web\UnprocessableEntityHttpException;

class CommonHelper
{
    public static $result = array();
    public static $macAddr;            //第一个mac地址
    const TAG_WX = 'msgwx_';
    const TAG_MOBILE = 'msgmb_';

    /**
     * 返回 array 数据格式 api 自动转为 json
     *
     * @param int $code 状态码 注意：要符合http状态码
     * @param string $message 返回的报错信息
     * @param array|object $data 返回的数据结构
     * @return mixed
     */
    public static function api($code = 404, $message = '未知错误', $data = [])
    {
        Yii::$app->response->setStatusCode($code, $message);
        Yii::$app->response->data = $data ? ArrayHelper::toArray($data) : [];

        return Yii::$app->response->data;
    }

    /**
     * 获取设备客户端信息
     *
     * @return mixed|string
     */
    public static function detectVersion()
    {
        return Yii::$app->request->userAgent;
    }

    /**
     * 解析错误
     *
     * @param $firstErrors
     * @return bool|string
     */
    public static function analyErr($firstErrors)
    {
        if (!is_array($firstErrors) || empty($firstErrors)) {
            return false;
        }

        $errors = array_values($firstErrors)[0];
        return $errors ?? '未捕获到错误信息';
    }

    /**
     * @return false|string
     * @throws yii\base\InvalidConfigException
     */
    public static function getUrl()
    {
        $url = explode('?', Yii::$app->request->getUrl())[0];
        $matching = '/' . Yii::$app->id . '/';
        if (substr($url, 0, strlen($matching)) == $matching) {
            $url = substr($url, strlen($matching), strlen($url));
        }

        if (substr($url, 0, 1) === '/') {
            $url = substr($url, 1, strlen($url));
        }

        return $url;
    }

    /**
     * @param $value
     * @return mixed
     */
    public static function htmlEncode($value)
    {
        if (!is_array($value)) {
            $value = Json::decode($value);
        }

        $array = [];
        foreach ($value as $key => &$item) {
            if (!is_array($item)) {
                $array[$key] = Html::encode($item);
            } else {
                $array[$key] = self::htmlEncode($item);
            }
        }

        return $array;
    }

    /**
     * @param $ip
     * @param bool $long
     * @return bool|string
     */
    public static function analysisIp($ip, $long = true)
    {
        if (empty($ip)) {
            return false;
        }

        if ('127.0.0.1' == $ip) {
            return '本地';
        }

        if ($long === true) {
            if (((int)$ip) > 1000) {
                return '无法解析';
            }
        }

        $ipData = \Zhuzhichao\IpLocationZh\Ip::find($ip);

        $str = '';
        isset($ipData[0]) && $str .= $ipData[0];
        isset($ipData[1]) && $str .= ' · ' . $ipData[1];
        isset($ipData[2]) && $str .= ' · ' . $ipData[2];

        return $str;
    }


    /**
     * 解析ip
     *
     * @param $ip
     * @return mixed|string[]
     * @author wangxiang
     */
    public static function ip2Location($ip)
    {
        $client = new Client(['verify' => false]);
//        $url = 'http://ip.taobao.com/service/getIpInfo2.php?ip=' . $ip . '&accessKey=alibaba-inc';
        $url = 'http://ip.taobao.com/service/getIpInfo.php?ip=' . $ip . '&accessKey=alibaba-inc';
        $response = $client->get($url);
        $res = json_decode($response->getBody(), true);
        if ($res['code'] == 0) {
            return $res['data'];
        } else {
            return [
                'country' => '',
                'isp_id' => '',
                'queryIp' => '',
                'city' => '',
                'ip' => '',
                'isp' => '',
                'county' => '',
                'region_id' => '',
                'area_id' => '',
                'county_id' => '',
                'region' => '',
                'country_id' => '',
                'city_id' => '',
            ];
        }
    }

    public static function ip2Region($ip)
    {
        $ip2region = new \Ip2Region();
        $info = $ip2region->btreeSearch($ip);
        if (empty($info['region'])) {
            return self::ip126($ip);
        }

        return $info['region'];
    }

    /**
     * @apiName 调用126调用接口
     * @apiGroup
     * @apiParam {Number}
     * @apiParam {String}
     * @param $ip
     * @return string
     * @author loujie
     */
    public static function ip126($ip)
    {
        $url = 'http://ip.ws.126.net/ipquery?ip=' . $ip;
        $res = self::https_request($url);
        $address = strstr($res, '{');
        $address = iconv('EUC-CN', 'UTF-8', $address);
        $address = trim($address);
        $address = str_replace('city', '"city"', $address);
        $address = str_replace('province', '"province"', $address);
        $array = json_decode($address, true);
        $city = $array['city'] ?? '';
        $province = $array['province'] ?? '';
        return $province . $city;
    }


    /**
     * curl  https请求
     *
     * @param $url
     * @param null $data
     * @return bool|string
     * @author chenyuebin
     */
    public static function https_request($url, $data = null, $header = null)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
        }
        //设置header头
        if (!empty($header)) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//        curl_setopt($curl, CURLINFO_HEADER_OUT, 1);
        $output = curl_exec($curl);
//        $curl_info = curl_getinfo($curl, CURLINFO_HEADER_OUT);
//        print_r($curl_info);
//        $errno= curl_errno($curl);
//        if ($errno) {
//            echo 'Errno:'.$errno.'<br>error:'.curl_error($curl).'<br>';
//        }
        curl_close($curl);
        return $output;
    }

    /**
     * 白友接口请求
     * @param string $url
     * @param array $params
     * @param $data
     * @param $header
     * @return array
     * @throws \Exception
     */
    public static function baiyou_request(string $url, array $params = [], $data = null, $header = null): array
    {
        $url = Yii::$app->params['baiyou_host'] . $url;
        if ($params) {
            $query = http_build_query($params);
            $url .= "?{$query}";
        }
        if ($data) {
            $data = http_build_query($data);
//            $header = ["content-type:application/json; charset=UTF-8"];
        }
        $res = self::https_request($url, $data, $header);
//        var_dump($url);exit();
        $resArr = json_decode($res, true);
//        var_dump($resArr);exit();
        if (empty($resArr) || $resArr['code'] != 200) {
            throw new \Exception($resArr['message'] ?? '白友获取失败');
        }
        return $resArr['data'];
    }

    /**
     * 验证手机号
     *
     * @param $value
     * @return bool
     */
    public static function validateMobile($value): bool
    {
        return preg_match('/^1\d{10}$/', $value) ? true : false;
    }

    /**
     * 验证微信号
     *
     * @param $wechat_num
     * @return bool
     * @author chenyuebin
     */
    public static function checkWechat($wechat_num): bool
    {
        if (!preg_match('/(\d{6,20})|([a-zA-Z]{1}[-_a-zA-Z0-9\*]+)/u', $wechat_num)) {
            return false;
        }

        return true;
    }

    /**
     * 手机号码归属地查询
     *
     * @param $tel
     * @return array
     * @author chenyuebin
     */
    public static function getLocation($tel)
    {
        if (is_numeric($tel)) {
            if (!preg_match("/^1[3456789]\d{9}$/", $tel)) return ['code' => 200, 'status' => false, 'msg' => 'Cell phone number error!'];
            $curl = curl_init();
            $url = 'http://apis.juhe.cn/mobile/get?phone=' . $tel . '&key=c2e4a5c772127a38b9533a83b2068815';
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $data = curl_exec($curl);
            curl_close($curl);
            $data = json_decode($data, true);
            if ($data['resultcode'] != 200) {
                if (preg_match("/^1[3456789]\d{9}$/", $tel)) {
                    $s = file_get_contents('http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=' . $tel);
                    preg_match_all("/(\w+):'([^']+)/", $s, $m);
                    $a = array_combine($m[1], $m[2]);
                    $telArea = $a && isset($a['carrier']) ? iconv('GB2312', 'UTF-8', $a['carrier']) : '';
                } else {
                    $telArea = '';
                }
                return ['code' => 200, 'status' => true, 'data' => ['fullname' => $telArea]];
            }
            $response['province'] = $data['result']['province'];        // 归属地
            $response['city'] = $data['result']['city'];   // 城市
            $response['service'] = $data['result']['company'];     // 运行商
            $response['fullname'] = $data['result']['company'];            // 运行商全称
            return ['code' => 200, 'status' => true, 'data' => $response];
        } else {
            return ['code' => 200, 'status' => true, 'data' => array("province" => "", "city" => "", "service" => "", "fullname" => "")];
        }
    }

    /**
     * 发送钉钉提醒MARKDOWN
     *
     * @param $url
     * @param $post_data
     * @return false|string
     * @author chenyuebin
     */
    public static function sendDing($url, $post_data)
    {
        $options = array(
            'http' => array(
                'method' => 'POST',
                'header' => 'Content-type:application/json; charset=utf-8',
                'content' => $post_data,
                'timeout' => 15 * 60 // 超时时间（单位:s）
            )
        );
        $context = stream_context_create($options);
        $result = file_get_contents($url, false, $context);
        return $result;
    }

    /**
     * 获取url域名
     *
     * @param $url
     * @param $getTop
     * @return string
     * @author chenyuebin
     */
    public static function getTopHost($url, $getTop = 0)
    {
        $url = strtolower($url);//首先转成小写
        $hosts = parse_url($url);
        $host = $hosts['host'];

        // 获取顶级域名
        if ($getTop) {
            //查看是几级域名
            $data = explode('.', $host);
            $n = count($data);
            //判断是否是双后缀
            $preg = '/[\w].+\.(com|net|org|gov|edu)\.cn$/';
            if (($n > 2) && preg_match($preg, $host)) {
                //双后缀取后3位
                $host = $data[$n - 3] . '.' . $data[$n - 2] . '.' . $data[$n - 1];
            } else {
                //非双后缀取后两位
                $host = $data[$n - 2] . '.' . $data[$n - 1];
            }
        }

        return $host;
    }

    /**
     * 根据生日计算年龄
     *
     * @param $birthday
     * @return bool|false|int
     * @author chenyuebin
     */
    public static function birthday($birthday)
    {
        $age = strtotime($birthday);
        if ($age === false) {
            return false;
        }
        list($y1, $m1, $d1) = explode("-", date("Y-m-d", $age));
        $now = strtotime("now");
        list($y2, $m2, $d2) = explode("-", date("Y-m-d", $now));
        $age = $y2 - $y1;
        if ((int)($m2 . $d2) < (int)($m1 . $d1)) {
            $age -= 1;
        }
        return $age;
    }

    /**
     * 获取文件路径
     * @param string $url
     * @return string
     */
    public static function getFileUrlPath(string $url): string
    {
        if (empty($url)) {
            return $url;
        }

        $index = strpos($url, '/juliao/');
        if ($index === false) {
            return '';
        }

        return substr($url, $index);
    }

    /**
     * 获取文件配置url
     * @param string $url
     * @return string
     */
    public static function getFileConfigUrl(string $url): string
    {
        if (empty($url)) {
            return $url;
        }

        $path = self::getFileUrlPath($url);
        if (empty($path)) {
            return $url;
        }

        return Yii::$app->params['robot_image_host'] . $path;
    }

    /**
     * 解析消息内容【添加配置url】
     * @param string $content
     * @return string
     */
    public static function parseMessageContent(string $content): string
    {
        $wxid = '';
        $newContent = json_decode($content, true);
        if (is_array($newContent) === false) {
            $contentArr = explode(':', $newContent, 2);
            if (count($contentArr) < 2) {
                return self::getFileConfigUrl($content);
            }
            $wxid = $contentArr[0] . ':';
            $newContent = json_decode($contentArr[1], true);
            if (is_array($newContent) === false) {
                return self::getFileConfigUrl($content);
            }
        }

        if (isset($newContent['fileUrl'])) {
            $newContent['fileUrl'] = self::getFileConfigUrl($newContent['fileUrl']);
        }
        if (isset($newContent['Thumb'])) {
            $newContent['Thumb'] = self::getFileConfigUrl($newContent['Thumb']);
        }
        return $wxid . json_encode($newContent);
    }

    /**
     * 格式化除数
     * @param $num1
     * @param $num2
     * @return int|string
     */
    public static function getDivNumberFormat($num1, $num2)
    {
        if (!is_numeric($num2) || ($num2 > 0 && !is_numeric($num1))) {
            return '';
        }

        if (empty($num2)) {
            return '--';
        }

        if (empty($num1)) {
            return 0;
        }

        return number_format($num1 / $num2, 2, '.', '');
    }

    // ================================= 获取访客操作系统：getOs、dstrpos ==========================

    /**
     * @Notes: 获取访客操作系统
     * @Interface getOS
     * @return bool|mixed|string|void
     * @author: chenyuebin
     * @Time: 2022/3/25 0025   13:43
     */
    public static function getOS()
    {
        $userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
        static $touchBrowserList = [
            'iphone',
            'phone',
            'mobile',
            'wap',
            'netfront',
            'java',
            'opera mobi',
            'HM NOTE',
            'opera mini',
            'ucweb',
            'windows ce',
            'symbian',
            'series',
            'webos',
            'sony',
            'dopod',
            'blackberry',
            'nokia',
            'samsung',
            'palmsource',
            'xda',
            'pieplus',
            'meizu',
            'midp',
            'cldc',
            'motorola',
            'foma',
            'docomo',
            'up.browser',
            'up.link',
            'blazer',
            'helio',
            'hosin',
            'huawei',
            'novarra',
            'coolpad',
            'webos',
            'techfaith',
            'palmsource',
            'amoi',
            'alcatel',
            'ktouch',
            'nexian',
            'ericsson',
            'philips',
            'sagem',
            'wellcom',
            'maui',
            'bunjalloo',
            'smartphone',
            'iemobile',
            'spice',
            'bird',
            'longcos',
            'pantech',
            'R7c',
            'gionee',
            'portalmmm',
            'jig browser',
            'hiptop',
            'benq',
            'haier',
            '^lct',
            '320x320',
            '240x320',
            '176x220',
            'windows phone',
            'zte-',
            'KOPO',
            'MI',
            'm1',
            'm2',
            'ATH',
            'iToolsVM',
            'HUAWEI',
            'SM-C5000',
            'KTU84P',
            'OPPO',
            'EVA-',
            'SM-',
            'PE-TL10',
            'HTC',
            'vivo',
            'H60-',
            'Nexus',
            'HLJ-XM-E2',
            'ZTE',
            'UOOGOU',
            'NX531J',
            'Redmi',
            'HS-X68T',
            'A51',
            'SCL-',
            'A31c',
            'Le',
            'BLN-',
            'ZUK',
            'KIW-',
            'GT-',
            'SAMSUNG',
            'Android',
        ];
        static $wmlBrowserList = [
            'cect',
            'compal',
            'ctl',
            'lg',
            'nec',
            'tcl',
            'alcatel',
            'ericsson',
            'bird',
            'daxian',
            'dbtel',
            'eastcom',
            'pantech',
            'dopod',
            'philips',
            'haier',
            'konka',
            'kejian',
            'lenovo',
            'benq',
            'mot',
            'soutec',
            'nokia',
            'sagem',
            'sgh',
            'sed',
            'capitel',
            'panasonic',
            'zte',
            'sharp',
            'amoi',
            'panda',
            'sonyericsson',
        ];
        static $padList = ['ipad'];
        static $wexin = ['MicroMessenger'];

        $brower = [
            '/Windows NT 10.0/i' => 'Windows 10',
            '/Windows NT 6.3/i' => 'Windows 8.1',
            '/Windows NT 6.2/i' => 'Windows 8',
            '/Windows NT 6.1/i' => 'Windows 7',
            '/Windows NT 6.0/i' => 'Windows Vista',
            '/Windows NT 5.2/i' => 'Windows Server 2003/XP x64',
            '/Windows NT 5.1/i' => 'Windows XP',
            '/Windows xp/i' => 'Windows XP',
            '/Windows NT 5.0/i' => 'Windows 2000',
            '/Windows me/i' => 'Windows ME',
            '/win98/i' => 'Windows 98',
            '/win95/i' => 'Windows 95',
            '/win16/i' => 'Windows 3.11',
            '/mac_powerpc/i' => 'Mac OS X 9',
            '/macintosh|mac os x/i' => 'Mac OS X', //'/linux/i' => 'Linux',
            '/unix/i' => 'Unix',
            '/bsd/i' => 'BSD',
            '/ubuntu/i' => 'Ubuntu',
        ];

        if ($v = self::dstrpos($userAgent, $padList, true)) {
            return $v ?: '';
        } elseif (($v = self::dstrpos($userAgent, $touchBrowserList, true))) {
            return $v ?: '';
        } elseif (($v = self::dstrpos($userAgent, $wmlBrowserList, true))) {
            return $v ?: '';
        } else {
            foreach ($brower as $regex => $value) {
                if (preg_match(strtolower($regex), strtolower($userAgent))) {
                    return $value ?: '';
                }
            }
        }
        return '';
    }

    public static function dstrpos($string, $arr, $returnValue = false)
    {
        if (empty($string)) {
            return false;
        }

        foreach ((array)$arr as $v) {
            if (strpos($string, $v) !== false) {
                $return = $returnValue ? $v : true;

                return $return;
            }
        }

        return false;
    }

    // ======================================= 获取mac地址：GetMac、getLinux、getWindows =======================

    /**
     * @Notes: 获取mac地址
     * @Interface GetMac
     * @param $OS
     * @return mixed
     * @author: chenyuebin
     * @Time: 2022/3/25 0025   14:01
     */
    public static function GetMac($OS)
    {
        switch (strtolower($OS)) {
            case "unix":
                break;
            case "solaris":
                break;
            case "aix":
                break;
            case "linux":
                self::getLinux();
                break;
            default:
                self::getWindows();
                break;
        }

        return self::$macAddr;
    }

    /**
     * @Notes: liunx系统
     * @Interface getLinux
     * @return mixed
     * @author: chenyuebin
     * @Time: 2022/3/25 0025   13:57
     */
    public static function getLinux()
    {
        @exec("ifconfig -a", self::$result);
        $tem = array();
        foreach (self::$result as $val) {
            if (preg_match("/[0-9a-f][0-9a-f][:-]" . "[0-9a-f][0-9a-f][:-]" . "[0-9a-f][0-9a-f][:-]" . "[0-9a-f][0-9a-f][:-]" . "[0-9a-f][0-9a-f][:-]" . "[0-9a-f][0-9a-f]/i", $val, $tem)) {
                self::$macAddr = $tem[0];//多个网卡时，会返回第一个网卡的mac地址，一般够用。
                break;
                //$this->macAddrs[] = $temp_array[0];//返回所有的mac地址
            }
        }
        unset($temp_array);
        return self::$macAddr;
    }

    /**
     * @Notes: Windows系统
     * @Interface getWindows
     * @author: chenyuebin
     * @Time: 2022/3/25 0025   13:58
     */
    public static function getWindows()
    {
        exec('/sbin/arp -a 2>&1', $array, $return_val);
        foreach ($array as $value) {
            //匹配结果放到数组$mac_array
            if (strpos($value, $_SERVER["REMOTE_ADDR"]) && preg_match("/(:?[0-9A-F]{2}[:-]){5}[0-9A-F]{2}/i", $value, $mac_array)) {
                self::$macAddr = $mac_array[0];
                break;
            }
        }
        return self::$macAddr;
    }

    /**
     * 数字精度格式化
     * @param $number
     * @param int $decimals 精度【=0整形 >0浮点】
     * @return float|int
     */
    public static function getNumberFloorFormat($number, int $decimals)
    {
        if ($decimals <= 0) {
            return (int)$number;
        }

        $rate = pow(10, $decimals);
        return floor($number * $rate) / $rate;
    }

    /**
     * 过滤标点空格
     * @param string $str
     * @return string
     */
    public static function getKeywordsFormat(string $str): string
    {
//        $a = '测试<>《》！*(^)$%~!@#$…&%￥—+=、。，；。.,?!‘’“”""\'\'：·`文本 1';
//        $str = "!@#$%^&*（中'文：；﹑•中'文中'文().,<>|[]'\"";
        // 中文标点
        $char = "。、！？：；﹑•＂…‘’“”〝〞∕¦‖—　〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔！¡？¿﹖﹌﹏﹋＇´ˊˋ―﹫︳︴¯＿￣﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼（）￥，·";
        $pattern = [
            "/[[:punct:]]/i", //英文标点符号
            '/['.$char.']/u', //中文标点符号
            '/[ ]/',
        ];
        return preg_replace($pattern, '', $str);
    }

    /**
     * 解析get query
     * @param string $query
     * @return array
     */
    public static function convertUrlQueryToArr(string $query): array
    {
        $queryParts = explode('&', $query);
        $params = [];
        foreach ($queryParts as $param) {
            $item = explode('=', $param);
            $params[$item[0]] = $item[1] ?? '';
        }
        return $params;
    }

    /**
     * @param string $str 加密内容
     * @param int $type 1微信 2手机
     * @param string $key
     * @return string
     */
    public static function encrtyp($str, $key='jgylkj')
    {
        $data = openssl_encrypt($str, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, '0102030405060708');
        return base64_encode($data);
    }

    public static function decrypt($str, $key='jgylkj')
    {
//        $data = openssl_decrypt(base64_decode(urldecode($str)), 'aes-128-cbc', $key, OPENSSL_RAW_DATA, '0102030405060708');
        $data = openssl_decrypt(base64_decode($str), 'aes-128-cbc', $key, OPENSSL_RAW_DATA, '0102030405060708');
        return $data;
    }

    /**
     * 获取解密关键词
     * @param string $keywords
     * @return string
     */
    public static function getDecryptKeywords(string $keywords): string
    {
        if (strpos($keywords,self::TAG_WX) === 0 || strpos($keywords,self::TAG_MOBILE) === 0) {
            $keywords = self::decrypt(strpos($keywords,self::TAG_WX) === 0
                ? str_replace(self::TAG_WX, '', $keywords)
                : str_replace(self::TAG_MOBILE, '', $keywords));
        }
        return $keywords;
    }

    /**
     * 解析手机号码归属地
     * @param $tel
     * @return string
     */
    public static function tel2address($tel)
    {
//        $ctx = stream_context_create(array('http' => array('timeout' => 30)));
        $res = file_get_contents('http://cx.shouji.360.cn/phonearea.php?number=' . $tel);
        if ($res) {
            $res = iconv('gb2312', 'utf-8', $res);
            $res = json_decode($res, true);
            if (is_array($res)) {
                $province = $res['data']['province'] ?? '';
                $city = $res['data']['city'] ?? '';
                return "{$province}_{$city}";
            }
        }
        return "未知";
    }

    public static function explode(string $separator, string $string): array
    {
        if (empty($string)) {
            return [];
        }
        return explode($separator, $string);
    }

    /**
     * 字符串格式转换,去掉空格,替换中文逗号
     * @param $str
     * @return mixed|string
     */
    public static function strFormat($str)
    {
        if (!$str) {
            return '';
        }
        $str = str_replace(' ', '', $str);
        $str = str_replace('，', ',', $str);
        return $str;
    }

    /**
     * 生成auth_key
     * @param int $count 长度
     * @param string $chars 随机字符串【不填，则默认】
     * @param int $unique 随机字符串是否唯一【1是、0否】
     * @return array|string
     */
    public static function getRandomAuthKey(int $count = 6, string $chars='', int $unique = 0): string
    {
        $chars = $chars ?: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        if ($unique) {
            $tmp = range(0, strlen($chars)-1);
            shuffle($tmp);
            $keys = array_slice($tmp, 0, $count);
            unset($tmp);
        } else {
            $keys = array_rand(range(0, strlen($chars)-1), $count);
        }

        $buff = [];
        foreach($keys as $value) {
            $buff[] = $chars[$value];
        }

        return implode('', $buff);
    }

    /**
     * 格式化数字
     * @param $num
     * @return string
     */
    public static function getNumFormat($num)
    {
        return is_null($num) ? '' : $num;
    }

    /**
     * 格式化列表
     * @param array $list
     * @param array $options
     * @return array
     */
    public static function getListCondition(array $list, array $options): array
    {
        $options['value_column'] = $options['value_column'] ?? 'id';
        $options['label_column'] = $options['label_column'] ?? 'name';
        $data = [];
        foreach ($list as $row) {
            $data[] = [
                'value' => $row[$options['value_column']],
                'label' => $row[$options['label_column']],
            ];
        }
        return $data;
    }

    /**
     * 格式化url
     * @param string $url
     * @return string
     */
    public static function getUrlFormat(string $url): string
    {
        if (empty($url)) {
            return '';
        }
        return ValidatorHelper::validateUrl($url) ? $url : "http://{$url}";
    }

    /**
     * 格式化大小
     * @param string $url
     * @return string
     */
    public static function getFileSizeFormat(int $size): string
    {
        $unit = 1024;
        $unitArr = ['B', 'KB', 'MB', 'GB'];
        $index = 0;
        $res = 0;
        while (true) {
            $res = $size / pow($unit, $index);
            if ($res > $unit && $index < 3) {
                $index++;
                continue;
            }
            break;
        }
        $res = round($res * 100) / 100;// 保留两位小数
        return $res." ".$unitArr[$index];
    }

    /**
     * 获取推荐人
     * @param string $name
     * @return string
     */
    public static function getRankNameStr(string $name): string
    {
        if (empty($name)) {
            return '';
        }
        return mb_substr($name, 0, 1).'**';
    }
}
